#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include"util.hpp"
#include<unordered_map>
#include<sstream>

namespace CH
{
	class DataManager
	{
	private:
		std::string _back_file;//备份文件持久化存储文件
		std::unordered_map<std::string, std::string> _table;//用来管理备份文件的数据，《文件名，唯一值》
	public:
		DataManager(const std::string& back_file)
			:_back_file(back_file)
		{
			InitLoad();
		}

		//按特定的字符来分割字符串，放到数组中
		void Split(const std::string& body, const std::string& sep, std::vector<std::string>* arry)
		{
			int start = 0,pos=0;
			while (true)
			{
				pos = body.find(sep,start);
				if (pos == std::string::npos)
				{
					break;
				}
				//从哪里开始，截取多少个
				std::string tmp = body.substr(start,pos-start);
				arry->push_back(tmp);
				start = pos + sep.size();
			}
			if (pos < body.size())
			{
				arry->push_back(body.substr(pos));
			}
		}
		//加载持久化存储文件，将持久化存储文件中的数据放入哈希表中进行管理
		bool InitLoad()
		{
			//从文件中读取文件信息
			FileUtil fu(_back_file);
			std::string body;//将文件信息放到body中
			fu.GetContent(&body);
			//将数据解析，放入哈希表中进行管理
			std::vector<std::string> arry;
			//将持久化存储文件中一条条文件数据，存入数组中
			Split(body, "\n", &arry);
			//将文件的名字和唯一值放入哈西表中
			for (auto& a : arry)
			{
				//a.txt a.txt-123456789
				std::vector<std::string> tmp;
				Split(a, " ", &tmp);
				if (tmp.size() != 2){
					continue;
				}
				_table[tmp[0]] = tmp[1];
			}
			return true;
		}

		//将哈希表中的数据放入持久化存储文件中
		bool Storage()
		{
			//获取哈希表中的所有数据
			std::stringstream ss;
			auto it = _table.begin();
			while (it != _table.end())
			{
				ss << it->first << " " << it->second <<"\n";;
				it++;
			}
			//将其放入持久化存储文件中
			FileUtil fu(_back_file);
			fu.SetContent(ss.str());
			return true;
		}

		//在哈希表中插入数据
		bool Insert(const std::string& key,const std::string& value)
		{
			_table[key] = value;
			//将新插入的数据，进行持久化存储文件的保存
			Storage();
			return true;
		}

		//更新该文件的唯一值
		bool Update(const std::string& key, const std::string& value)
		{
			_table[key] = value;
			//将新插入的数据，进行持久化存储文件的保存
			Storage();
			return true;
		}

		//根据文件名，找到唯一值
		bool GetOneByKey(const std::string& key, std::string* value)
		{
			auto it = _table.find(key);
			if (it == _table.end()){
				return false;
			}
			*value = it->second;
			return true;
		}
	};
}